/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics/renderer
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AERenderLoopHelper.h
// Author:		Gianluca Belardelli
// Date:		15/06/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AERENDERLOOPHELPER_H_
#define _AERENDERLOOPHELPER_H_

/// \brief
///   Render Loop Helper class
/// 
/// This class provides helper functionality for writing custom render loops. All methods defined
/// in this class may only be used inside render loops (not e.g. in entity code).
/// 
/// The default VisionRenderLoop_cl implementation provides a good insight into how these methods
/// are typically used.
class AERenderLoopHelper
{
// Members
public:
	/// \brief Flags that specify which render targets should be cleared.
	enum AEClearTargetFlags
	{
		AECTF_COLOR        = 1 << 0,                                     ///< Clears all color render targets.
		AECTF_STENCIL      = 1 << 1,                                     ///< Clears the stencil buffer.
		AECTF_DEPTH        = 1 << 2,                                     ///< Clears the depth buffer.
		AECTF_DEPTHSTENCIL = AECTF_STENCIL | AECTF_DEPTH,                  ///< Clears the depth/stencil buffer (usually faster than just clearing one of them).
		AECTF_ALL          = AECTF_COLOR | AECTF_STENCIL | AECTF_DEPTH,     ///< Clears all buffers (color + depth + stencil).
	};

// Methods
public:
	AE_DLLIMPEXP AERenderLoopHelper( void );
	AE_DLLIMPEXP ~AERenderLoopHelper( void );

	/// @name Render Helper Functions
	/// @{
	///
	/// \brief
	///   Clears the depth, stencil, and/or color buffers.
	/// 
	/// This method may exclusively be called in render loop implementations.
	/// 
	/// \param uiBufferFlags
	///   One or more of the flags defined in VClearTargetFlags_e can be specified.
	///   For performance reasons it is strongly recommended to clear depth and stencil buffers together, instead of separately.
	/// 
	/// \param iClearColor
	///   Color with which to clear the color buffer.
	/// 
	/// \param fDepthRef
	///   Depth value with which to clear the depth buffer.
	/// 
	/// \param iStencilRef
	///   Stencil value with which to clear the stencil buffer.
	/// 
	/// \param iRTMask
	///   Mask indicating which color render targets to clear. Bit 0 represents RT 0, Bit 1
	///   represents RT 1, and so on. This does not have any effect if the VIS_COLORBUFFER flag is
	///   not set in the iBufferFlags, or if the respective render target is not set.
	AE_DLLIMPEXP void ClearScreen( AEUINT32 uiBufferFlags = AECTF_ALL, AEColor colClearColor = AEColor( 0, 0, 0, 0 ), AEFLOAT32 fDepthRef = 1.0f, AEINT32 nStencilRef = 0, AEINT32 nRTMask = 1 ) const;

    ///
    /// @name Visibility Helper Functions
    /// @{
    ///

    /// \brief
    ///   Renders scheduled hardware occlusion queries.
    /// 
    /// This method temporarily disables multi-sample anti-aliasing (if it was previously enabled)
    /// and calls VisRenderContext_cl::RenderScheduledOcclusionTests.
    /// 
    /// \sa VisRenderContext_cl::RenderScheduledOcclusionTests
    AE_DLLIMPEXP void PerformHardwareOcclusionQuery( void );

    /// \brief
    ///   Renders scheduled hardware occlusion queries for pixel counters.
    /// 
    /// This method temporarily disables multi-sample anti-aliasing (if it was previously enabled)
    /// and calls VisRenderContext_cl::RenderScheduledPixelCounterTests.
    /// 
    /// \sa VisRenderContext_cl::RenderScheduledPixelCounterTests
    AE_DLLIMPEXP void PerformHardwarePixelCounterQuery( void );

	/// \brief
	///   Renders a collection of static geometry instances with the passed shader.
	/// 
	/// For best performance, the order of the static geometry instances in the collection should
	/// be so that render state changes are minimized. The Vision Engine will automatically take
	/// care of minimizing redundant state changes, but does not resort geometry instances on the
	/// fly.
	/// 
	/// Most of all, it should be taken care that VisStaticSubmeshInstance_cl objects are not
	/// interspersed with other static geometry instance types.
	/// 
	/// \param geoInstances
	///   Collection of static geometry instances to render.
	/// 
	/// \param Shader
	///   Shader with which to render the static geometry instances.
	/// 
	/// \sa VisRenderLoopHelper_cl::RenderStaticGeometrySurfaceShaders
	AE_DLLIMPEXP void RenderStaticGeometryWithShader(const AEStaticGeometryInstanceCollection &refGeoInstances, AECompiledShaderPass &refShader );

	/// \brief
	///   Renders a collection of static geometry instances with the shaders assigned to their
	///   respective surfaces.
	/// 
	/// For best performance, the order of the static geometry instances in the collection should
	/// be so that render state changes are minimized. The Vision Engine will automatically take
	/// care of minimizing redundant state changes, but does not resort geometry instances on the
	/// fly.
	/// 
	/// Most of all, it should be taken care that VisStaticSubmeshInstance_cl objects are not
	/// interspersed with other static geometry instance types.
	/// 
	/// \param geoInstances
	///   Collection of static geometry instances to render.
	/// 
	/// \param ePassType
	///   The pass type to render.
	/// 
	/// \param iTagFilter
	///   If iTagFilter==VTF_IGNORE_TAGGED_ENTRIES, tagged entries inside the specified collection will not be rendered.
	/// 
	/// \sa VisRenderLoopHelper_cl::RenderStaticGeometryWithShader
	AE_DLLIMPEXP void RenderStaticGeometrySurfaceShaders( const AEStaticGeometryInstanceCollection &refGeoInstances, AEPassType ePassType );


};

#endif // _AERENDERLOOPHELPER_H_
